package spring.boot.btc.model;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import spring.boot.btc.common.BlockProperty;
import spring.boot.btc.utils.BaseUtils;
import spring.boot.btc.utils.HashUtils;
import spring.boot.btc.utils.RsaUtils;

/**
 * 交易输入
 */
@Data
@Slf4j
public class TransactionInput {

    /**
     * 交易输入hash
     */
    private String hash;


    /**
     * 引用的交易hash 指的是 Transaction类对象中的hash
     */
    private String quoteTransactionHash;

    /**
     * 引用的交易中的第几个output 从0开始
     */
    private int quoteTransactionOutputNum;

    /**
     * 打款人公钥
     */
    private String publicKey;

    /**
     * 打款人地址的hash 0表示挖矿
     */
    private String address;

    /**
     * 0=创世区块
     * 1=挖矿
     * 2=真人转账
     */
    private int type;

    /**
     * 表示打钱方打了多少钱
     */
    private long money;

    /**
     * 签名
     */
    private String sign;


    public static TransactionInput getSystemInput() {
        return new TransactionInput(RsaUtils.getPublicKey(BlockProperty.sysSignKey), 10, "0", 0);
    }

    public static TransactionInput getFirstInput() {
        return new TransactionInput("0", 0, "0", 0);
    }

    public TransactionInput() {
    }

    public TransactionInput(String publicKey, long money, String quoteTransactionHash, int quoteTransactionOutputNum) {
        this.publicKey = publicKey;
        this.money = money;
        this.quoteTransactionHash = quoteTransactionHash;
        this.quoteTransactionOutputNum = quoteTransactionOutputNum;
        initAddress();
        initSign();
        initHash();
    }

    private void initAddress() {
        this.address = HashUtils.sha256(publicKey);
        if ("0".equals(publicKey)) {
            //创世区块
            this.type = 0;
        } else if ("0".equals(quoteTransactionHash)) {
            //挖矿
            this.type = 1;
        } else {
            //真人转账
            this.type = 2;
        }
    }

    private void initSign() {
        StringBuilder sb = new StringBuilder();
        sb.append(publicKey);
        sb.append(address);
        sb.append(money);
        sb.append(type);
        sb.append(quoteTransactionHash);
        sb.append(quoteTransactionOutputNum);
        byte[] data = sb.toString().getBytes();
        byte[] privateKey = null;
        if (type == 0) {
            //创世区块
            this.sign = "0";
        } else if (type == 1) {
            //挖矿
            privateKey = BlockProperty.sysSignKey.get(RsaUtils.PRIVATE_KEY).getEncoded();
            try {
                this.sign = BaseUtils.toBase64(RsaUtils.signByPrivateKey(data, privateKey));
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                this.sign = "-1";
            }
        } else if (type == 2) {
            //真人转账
            privateKey = Wallet.getInstance().getPrivateKey().getEncoded();
            try {
                this.sign = BaseUtils.toBase64(RsaUtils.signByPrivateKey(data, privateKey));
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                this.sign = "0";
            }
        }
    }

    private void initHash() {
        StringBuilder sb = new StringBuilder();
        sb.append(publicKey);
        sb.append(address);
        sb.append(money);
        sb.append(type);
        sb.append(sign);
        sb.append(quoteTransactionHash);
        sb.append(quoteTransactionOutputNum);
        this.hash = HashUtils.sha256(sb.toString());
    }
}
